package cn.topcodes.tcsf.app.web.controller.admin;

import cn.topcode.unicorn.utils.DateUtil;
import cn.topcode.unicorn.utils.In;
import cn.topcode.unicorn.utils.ValidationUtil;
import cn.topcodes.tcsf.admin.commons.api.controller.admin.AdminController;
import cn.topcodes.tcsf.admin.commons.api.domain.ApiResponseEntity;
import cn.topcodes.tcsf.admin.commons.domain.Page;
import cn.topcodes.tcsf.admin.commons.domain.ValueRangeConstant;
import cn.topcodes.tcsf.app.domain.entity.AppClient;
import cn.topcodes.tcsf.app.domain.entity.AppUser;
import cn.topcodes.tcsf.app.domain.entity.DailyActiveUsers;
import cn.topcodes.tcsf.app.domain.form.QuickCreateAppUserForm;
import cn.topcodes.tcsf.app.domain.report.RespAppUserInfo;
import cn.topcodes.tcsf.app.domain.report.UserRetentionVo;
import cn.topcodes.tcsf.app.service.AppClientService;
import cn.topcodes.tcsf.app.service.AppUserService;
import cn.topcodes.tcsf.app.service.DailyActiveUsersService;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Example;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.naming.Binding;
import javax.persistence.EntityNotFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Unicorn
 * @date 2017/5/5
 */
@Controller
@RequestMapping("/admin/app-user")
public class AppUserAdminController extends AdminController<AppUser, AppUser, AppUser> {

    @Autowired
    private AppUserService appUserService;

    @Autowired
    private AppClientService appClientService;

    @Autowired
    private DailyActiveUsersService dauService;

    @Override
    protected String getPageFolder() {
        return "app/admin/app-user";
    }

    /**
     * 重置密码页面
     *
     * @param id
     * @param model
     * @return
     */
    @RequestMapping(value = "reset-password", method = RequestMethod.GET)
    public String resetPassword(@RequestParam(required = true) Long id, Model model) {
        model.addAttribute("id", id);
        return "app/admin/app-user/reset-password";
    }

    /**
     * 重置APP用户密码
     *
     * @param id
     * @param newPassword
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "reset-password", method = RequestMethod.POST)
    public ApiResponseEntity resetPassword(
            @RequestParam(required = true) Long id,
            @RequestParam(required = true) String newPassword,
            @RequestParam(required = true) String adminPassword
    ) {
        Assert.isTrue(newPassword.length() >= 6 && newPassword.length() <= 20, "密码长度为6~20个字符");
        if (!this.validateOperation(adminPassword)) {
            return ApiResponseEntity.buildIllegalArgument("管理密码输入错误");
        }
        AppUser appUser = this.appUserService.findOne(id);
        if (appUser == null)
            throw new EntityNotFoundException("用户不存在,id:" + id);
        this.appUserService.resetPassword(id, newPassword);
        return ApiResponseEntity.buildOK();
    }

    /**
     * 快速创建app用户
     *
     * @param reqQuickCreateAppUser
     * @param result
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "quick-create", method = RequestMethod.POST)
    public ApiResponseEntity quickCreate(
            @Valid QuickCreateAppUserForm reqQuickCreateAppUser,
            BindingResult result
    ) {
        ValidationUtil.validate(result);
        AppUser appUser = new AppUser();
        appUser.setUsername(reqQuickCreateAppUser.getUsername());
        appUser.setRealName(reqQuickCreateAppUser.getRealName());
        appUser.setPassword(reqQuickCreateAppUser.getPassword());
        appUser.setGender(ValueRangeConstant.Gender.GENDER_UNKNOWN);
        appUser.setRole(AppUser.ROLE_NORMAL);
        this.getService().create(appUser);
        return ApiResponseEntity.buildOK();
    }

    @Override
    public String detail(Long id, HttpServletRequest request, Model model) {
        List<AppClient> appClients = appClientService.findByAppUserId(id);
        model.addAttribute("appClients", appClients);
        return super.detail(id, request, model);
    }

    @Override
    @ResponseBody
    public ApiResponseEntity<Void> update(HttpServletRequest request, @Valid AppUser form, BindingResult result) {
        ValidationUtil.validate(result);
        this.appUserService.updateAppUser(form);
        return ApiResponseEntity.buildOK();
    }


    @ResponseBody
    @RequestMapping(value = "year-dau", method = RequestMethod.GET)
    public ApiResponseEntity yearDau(@RequestParam(required = true) Long appUserId) {
        Map<String, Map> years = new HashMap<>();

        Date now = new Date();
        String year = DateUtil.format(now, "yyyy");
        years.put(year, year(appUserId, now));

        now.setYear(now.getYear() - 1);
        String lastYear = DateUtil.format(now, "yyyy");
        years.put(lastYear, year(appUserId, now));

        return ApiResponseEntity.buildOK(years);
    }

    private Map<String, Integer> year(Long appUserId, Date date) {
        Map<String, Integer> map = new HashMap<>();

        Date start = (Date) date.clone();
        start.setMonth(0);
        start.setDate(1);
        start = DateUtil.change0H0M0S(start);
        Date end = (Date) date.clone();
        end.setMonth(11);
        end.setDate(31);
        end = DateUtil.change23H59M59S(end);

        List<DailyActiveUsers> list = this.dauService.findBy(appUserId, start, end);
        for (DailyActiveUsers dau : list) {
            String dateStr = DateUtil.format(dau.getDauDate(), DateUtil.YYYY_MM_DD);
            map.put(dateStr, dau.getCount());
        }
        return map;
    }

    @RequestMapping(value = "newAccountsPageList", method = RequestMethod.GET)
    @ResponseBody
    public ApiResponseEntity<Page<AppUser>> newAccountsPageList(HttpServletRequest request,
                                                                @ApiParam("页号") @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNumber,
                                                                @ApiParam("每页条数") @RequestParam(value = "size", required = false, defaultValue = "10") Integer pageSize) {
        Map<String, String[]> searchParams = request.getParameterMap();
        Page<AppUser> page = this.appUserService.findPageAndSearchDate(searchParams, pageNumber.intValue(), pageSize.intValue());
        Page<AppUser> appUserPage = this.entity2Vo(page, request);
        ApiResponseEntity<Page<AppUser>> apiResponse = ApiResponseEntity.buildOK();
        return apiResponse.setBody(appUserPage);
    }

    @RequestMapping(value = "OnlineAccountPageList", method = RequestMethod.GET)
    @ResponseBody
    public ApiResponseEntity<Page<AppUser>> OnlineAccountPageList(HttpServletRequest request,
                                                                  @ApiParam("页号") @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNumber,
                                                                  @ApiParam("每页条数") @RequestParam(value = "size", required = false, defaultValue = "10") Integer pageSize) {
        Map<String, String[]> searchParams = request.getParameterMap();
        Page<AppUser> page = this.appUserService.findPageAndSearchAccountOnline(searchParams, pageNumber.intValue(), pageSize.intValue());
        Page<AppUser> appUserPage = this.entity2Vo(page, request);
        ApiResponseEntity<Page<AppUser>> apiResponse = ApiResponseEntity.buildOK();
        return apiResponse.setBody(appUserPage);
    }

    @RequestMapping(value = "activeAccountPageList", method = RequestMethod.GET)
    @ResponseBody
    public ApiResponseEntity<Page<AppUser>> activeAccountPageList(HttpServletRequest request,
                                                                  @ApiParam("页号") @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNumber,
                                                                  @ApiParam("每页条数") @RequestParam(value = "size", required = false, defaultValue = "10") Integer pageSize) {
        Map<String, String[]> searchParams = request.getParameterMap();
        Page<AppUser> page = this.appUserService.findPageAndSearchAccountActive(searchParams, pageNumber.intValue(), pageSize.intValue());
        Page<AppUser> appUserPage = this.entity2Vo(page, request);
        ApiResponseEntity<Page<AppUser>> apiResponse = ApiResponseEntity.buildOK();
        return apiResponse.setBody(appUserPage);
    }

    @RequestMapping(value = "appUserInfos", method = RequestMethod.GET)
    @ResponseBody
    public ApiResponseEntity<Page<RespAppUserInfo>> appUserInfos(HttpServletRequest request,
                                                                 @ApiParam("页号") @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNumber,
                                                                 @ApiParam("每页条数") @RequestParam(value = "size", required = false, defaultValue = "10") Integer pageSize) {
        Map<String, String[]> searchParams = request.getParameterMap();
        Page<RespAppUserInfo> pageAndSearchAccountByApp = this.appUserService.findPageAndSearchAccountByApp(searchParams, pageNumber.intValue(), pageSize.intValue());
        ApiResponseEntity<Page<RespAppUserInfo>> apiResponse = ApiResponseEntity.buildOK();
        return apiResponse.setBody(pageAndSearchAccountByApp);
    }

    @RequestMapping(value = "getUserRetention", method = RequestMethod.GET)
    @ResponseBody
    public List<UserRetentionVo> UserRetention(HttpServletRequest request) {
        Map<String, String[]> searchParams = request.getParameterMap();
        List<UserRetentionVo> userRetention = this.appUserService.getUserRetention(searchParams);
        return userRetention;
    }

    @ResponseBody
    @RequestMapping(value = "changeRole", method = RequestMethod.POST)
    public ApiResponseEntity changeRole(
            @RequestParam(required = true) Long id,
            @RequestParam(required = true) String auth,
            @RequestParam(required = true) String adminPassword
    ) {
        if (!this.validateOperation(adminPassword)) {
            return ApiResponseEntity.buildIllegalArgument("管理密码输入错误");
        }
        AppUser appUser = this.appUserService.findOne(id);
        if (appUser == null)
            throw new EntityNotFoundException("用户不存在,id:" + id);
        if ((AppUser.ROLE_ADMIN.equals(auth))) {
            //表示取消管理资格
            appUser.setRole(AppUser.ROLE_NORMAL);
        } else {
            //设为管理员
            appUser.setRole(AppUser.ROLE_ADMIN);
        }
        appUserService.update(appUser);
        return ApiResponseEntity.buildOK();
    }
}
